package com.vanhung.speedtest;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.os.Environment;
import android.util.Log;
import android.view.View;

public class AsyncUploader extends AsyncNetWorker {

	private static final String TAG = AsyncUploader.class.getSimpleName();

	public AsyncUploader(SpeedTestLauncher activity) {
		super(activity);
	}

	@Override
	protected void onPreExecute() {
		if (!mainAct.mCanceled) {
			Log.d(TAG, "mCanceled " + mainAct.mCanceled);
			btnStart.setText(R.string.mainbtn_up);
			updateProgress(0, 0);
		}
	}

	@Override
	protected Double doInBackground(String... urls) {
		HttpURLConnection connection = null;
		FileInputStream fileInputStream = null;
		DataOutputStream outputStream = null;

//		String pathToOurFile = Environment.getExternalStorageDirectory().getPath() + "/dummy.txt";
		String pathToOurFile = Environment.getExternalStorageDirectory().getPath() + "/" + FILE_NAME;

		String lineEnd = "\r\n";
		String twoHyphens = "--";
		String boundary = "*****";

		int bytesRead, bytesAvailable, bufferSize;
		int totalBytes = 0;
		byte[] buffer;
		int maxBufferSize = 1 * 1024;

		long up_time = 1;

		try {
			fileInputStream = new FileInputStream(new File(pathToOurFile));

			URL url = new URL(urls[0]);
			connection = (HttpURLConnection)url.openConnection();

			// Allow Inputs & Outputs
			connection.setDoInput(true);
			connection.setDoOutput(true);
			connection.setUseCaches(false);

			// Enable POST method
			connection.setRequestMethod("POST");

			connection.setRequestProperty("Connection", "Keep-Alive");
			connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

			outputStream = new DataOutputStream(connection.getOutputStream());
			outputStream.writeBytes(twoHyphens + boundary + lineEnd);
			outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile + "\"" + lineEnd);
			outputStream.writeBytes(lineEnd);

			bytesAvailable = fileInputStream.available();
			bufferSize = Math.min(bytesAvailable, maxBufferSize);
			buffer = new byte[bufferSize];

			// Read file
			bytesRead = fileInputStream.read(buffer, 0, bufferSize);

			long up_start = System.currentTimeMillis();

			long updateStart = System.currentTimeMillis();
			long updateDelta = 0;

			while (bytesRead > 0 && !isCancelled()) {
				outputStream.write(buffer, 0, bufferSize);

				totalBytes += bytesRead;

				bytesAvailable = fileInputStream.available();
				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				bytesRead = fileInputStream.read(buffer, 0, bufferSize);

//				if (updateDelta >= UPDATE_INTERVAL) {
//					up_time = System.currentTimeMillis() - up_start;
//					//int progress = (int) ((totalBytes / (double) EXPECTED_SIZE_IN_BYTES) * 100);
//					Message msg = Message.obtain(mHandler,
//							MSG_UPDATE_STATUS,
//							calculate(up_time, totalBytes));
//					//msg.arg1 = progress;
//					msg.arg2 = totalBytes;
//					mHandler.sendMessage(msg);
//					// Reset
//					updateStart = System.currentTimeMillis();
//					//bytesInThreshold = 0;
//				}
				updateDelta = System.currentTimeMillis() - updateStart;
				if (updateDelta != 0) Log.d(TAG, "updateDelta " + updateDelta + "  totalBytes " + totalBytes + " speed " + calculate(updateDelta, totalBytes));
			}

			outputStream.writeBytes(lineEnd);
			outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

			// Responses from the server (code and message)
			int serverResponseCode = connection.getResponseCode();
			String serverResponseMessage = connection.getResponseMessage();
			Log.d(TAG, "serverResponseCode = " + serverResponseCode + "  " + "serverResponseMessage = " + serverResponseMessage);

			up_time = System.currentTimeMillis() - up_start;
			Log.d(TAG, "up_time " + up_time);
			Log.d(TAG, "totalBytes " + totalBytes);

			fileInputStream.close();
			outputStream.flush();
			outputStream.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			try {
				if (outputStream != null) {
					outputStream.flush();
					outputStream.close();
				}
				if (fileInputStream != null) {
					fileInputStream.close();
				}
			}
			catch (Exception e) {
				Log.w(TAG, "Exception " + e.getMessage());
			}
		}

		return calculate(up_time, totalBytes);
	}

	@Override
	protected void onProgressUpdate(Double... progress) {
		double percent = progress[0];
		double speed = progress[1];

		updateProgress(percent, speed);
	}

	@Override
	protected void onPostExecute(Double speed) {
		updateProgress(100, speed);

		btnStart.setEnabled(true);
		btnStart.setText(R.string.mainbtn_start);
		btnCancel.setVisibility(View.INVISIBLE);

		mainAct.onUploadComplete();
	}

	@Override
	protected void updateProgress(double percent, double speed) {
		mProgressBar.setProgress((int)percent);
		mTxtProgress.setText(String.format("%d", (int)percent) + "%");

		mTxtUploadSpeed.setText(mDecimalFormater.format(speed) + KBIT_SEC);

		mainAct.setPointer(speed);
	}

}
